#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import psycopg2
import requests
import json
import time
import logging
from urllib.parse import unquote
import schedule

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('/Volumes/jdssd5/Project/python/pytools/music/music_scheduler.log', encoding='utf-8'),
        logging.StreamHandler()
    ]
)

class MusicScheduler:
    def __init__(self, db_config):
        self.db_config = db_config
        self.headers = {
            'accept': '*/*',
            'accept-language': 'zh-CN,zh;q=0.9',
            'priority': 'u=1, i',
            'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
            'sec-ch-ua-mobile': '?0',
            'sec-ch-ua-platform': '"macOS"',
            'sec-fetch-dest': 'empty',
            'sec-fetch-mode': 'cors',
            'sec-fetch-site': 'same-site',
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36'
        }
        
    def connect_db(self):
        """连接数据库"""
        try:
            conn = psycopg2.connect(**self.db_config)
            return conn
        except Exception as e:
            logging.error(f"数据库连接失败: {e}")
            return None
    
    def fetch_random_songs(self):
        """获取随机推荐歌曲"""
        try:
            url = "https://api.qqmp3.vip/api/songs.php?type=rand"
            response = requests.get(url, headers=self.headers, timeout=10)
            if response.status_code == 200:
                data = response.json()
                if data.get('code') == 200:
                    songs = data.get('data', [])
                    logging.info(f"成功获取 {len(songs)} 首随机推荐歌曲")
                    return songs
                else:
                    logging.error(f"获取随机推荐歌曲失败: {data.get('message', '未知错误')}")
            else:
                logging.error(f"HTTP请求失败，状态码: {response.status_code}")
        except Exception as e:
            logging.error(f"获取随机推荐歌曲时出错: {e}")
        return []
    
    def save_music_batch_to_db(self, songs):
        """将一批音乐数据保存到数据库"""
        if not songs:
            logging.warning("没有歌曲数据需要保存")
            return 0
            
        conn = self.connect_db()
        if not conn:
            return 0
            
        saved_count = 0
        try:
            cursor = conn.cursor()
            
            for song_data in songs:
                try:
                    # 插入音乐数据
                    insert_music_sql = """
                    INSERT INTO music (rid, name, artist, pic, src, file_path, extracted_song_name, extracted_artist)
                    VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
                    ON CONFLICT (rid) DO NOTHING
                    RETURNING id;
                    """
                    
                    cursor.execute(insert_music_sql, (
                        song_data.get('rid'),
                        song_data.get('name'),
                        song_data.get('artist'),
                        song_data.get('pic').replace('\\', '') if song_data.get('pic') else None,
                        song_data.get('src').replace('\\', '') if song_data.get('src') else None,
                        None,  # file_path
                        song_data.get('name'),  # extracted_song_name
                        song_data.get('artist')  # extracted_artist
                    ))
                    
                    result = cursor.fetchone()
                    if result:
                        music_id = result[0]
                        conn.commit()
                        
                        # 插入下载链接数据
                        if 'downurl' in song_data and song_data['downurl']:
                            for downurl_item in song_data['downurl']:
                                if '$$' in downurl_item:
                                    url_type, url_value = downurl_item.split('$$', 1)
                                    formatted_url = f"{url_type}: {url_value}"
                                    
                                    insert_download_url_sql = """
                                    INSERT INTO music_download_url (music_id, url_type, url_value, formatted_url)
                                    VALUES (%s, %s, %s, %s)
                                    ON CONFLICT DO NOTHING;
                                    """
                                    
                                    cursor.execute(insert_download_url_sql, (
                                        music_id,
                                        url_type,
                                        url_value,
                                        formatted_url
                                    ))
                        
                        # 保存原始JSON数据
                        insert_raw_data_sql = """
                        INSERT INTO music_raw_data (rid, raw_json)
                        VALUES (%s, %s)
                        ON CONFLICT (rid) DO NOTHING;
                        """
                        
                        cursor.execute(insert_raw_data_sql, (
                            song_data.get('rid'),
                            json.dumps(song_data, ensure_ascii=False)
                        ))
                        
                        conn.commit()
                        saved_count += 1
                        logging.info(f"成功保存歌曲: {song_data.get('name')} - {song_data.get('artist')}")
                    else:
                        logging.debug(f"歌曲已存在，跳过: {song_data.get('name')} - {song_data.get('artist')}")
                        
                except Exception as e:
                    logging.error(f"保存单首歌曲时出错: {e}")
                    conn.rollback()
                    
            cursor.close()
            conn.close()
            
            logging.info(f"成功保存 {saved_count} 首新歌曲到数据库")
            return saved_count
        except Exception as e:
            logging.error(f"保存歌曲批次到数据库时出错: {e}")
            if conn:
                conn.rollback()
                conn.close()
            return 0
    
    def collect_random_songs_batch(self):
        """收集一批随机推荐歌曲"""
        logging.info("开始收集一批随机推荐歌曲...")
        
        # 获取随机推荐歌曲
        random_songs = self.fetch_random_songs()
        
        if not random_songs:
            logging.warning("未能获取到随机推荐歌曲")
            return 0
            
        # 保存到数据库
        saved_count = self.save_music_batch_to_db(random_songs)
        logging.info(f"本次任务完成，新增 {saved_count} 首歌曲")
        return saved_count
    
    def start_scheduler(self):
        """启动定时任务调度器"""
        logging.info("启动音乐数据收集定时任务调度器...")
        
        # 设置定时任务 - 每1分钟执行一次
        schedule.every(1).minutes.do(self.collect_random_songs_batch)
        
        # 立即执行一次
        self.collect_random_songs_batch()
        
        # 启动调度器
        while True:
            schedule.run_pending()
            time.sleep(1)

def main():
    # 数据库配置
    db_config = {
        'host': 'localhost',
        'database': 'postgres',
        'user': 'lijun',
        'password': 'kuaile9hao',
        'port': 5432
    }
    
    # 创建调度器实例
    scheduler = MusicScheduler(db_config)
    
    # 启动定时任务
    try:
        scheduler.start_scheduler()
    except KeyboardInterrupt:
        logging.info("定时任务调度器已停止")
    except Exception as e:
        logging.error(f"定时任务调度器出现错误: {e}")

if __name__ == "__main__":
    main()